﻿using LJ.Abstractions.DependencyInjection;
using LJ.Abstractions.Exceptions;
using LJ.Abstractions.Extensions;
using LJ.Abstractions.Reflection;
using LJ.Socket.Server.Abstractions;
using LJ.Socket.Server.Abstractions.Attributes;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace LJ.Socket.Server.StraightChicken.Internal;

public class SocketServerHandlerManager : ISocketServerHandlerManager
{
    
    private readonly ConcurrentDictionary<string, SocketServerHandlerDescriptor> _socketServerHandlerDescriptors = [];

    private readonly IDependencyManager _dependencyManager;

    private readonly IReflectionManager _reflectionManager;
    public SocketServerHandlerManager(IDependencyManager dependencyManager, IReflectionManager reflectionManager)
    {
        _dependencyManager = dependencyManager;
        _reflectionManager = reflectionManager;


        //查找所有自动注册的服务实现类型进行注册
        var types = FindTypes();
        foreach (Type type in types)
        {
            var socketServerHandlerAttribute = type.GetCustomAttribute<SocketServerHandlerAttribute>();
            if (socketServerHandlerAttribute != null)
            {
                _dependencyManager.ServiceCollection.AddTransient(type);
                var eventType = GetEventType(type);
                _socketServerHandlerDescriptors.AddOrUpdate(socketServerHandlerAttribute.Name,
                    a => new SocketServerHandlerDescriptor(socketServerHandlerAttribute.Name,  eventType, type),
                    (a, b) => new SocketServerHandlerDescriptor(socketServerHandlerAttribute.Name, eventType, type));
            }

        }
    }

    public IReadOnlyCollection<SocketServerHandlerDescriptor> GetSocketServerHandlerDescriptors()
    {
        return [.. _socketServerHandlerDescriptors.Values];
    }

    public SocketServerHandlerDescriptor GetSocketServerHandlerDescriptor(string name) 
    { 
        if (_socketServerHandlerDescriptors.TryGetValue(name, out var handlerDescriptor))
        {
            return handlerDescriptor;
        }
        throw new AppException($"[SocketServerHandlerDescriptor] not : {name}");
    }

    private List<Type> FindTypes()
    {
        Type[] baseTypes = [typeof(ISocketServerHandler<>)];
        return _reflectionManager.GetTypes(type => baseTypes.Any(b => type.IsDeriveClassFrom(b)) && type.HasAttribute<SocketServerHandlerAttribute>());
    }

   
    private static Type GetEventType(Type type)
    {
        return type.GetTypeInfo()
            .ImplementedInterfaces
            .Single(r => r.IsGenericType && r.GetGenericTypeDefinition() == typeof(ISocketServerHandler<>))
            .GetGenericArguments()
            .Single();
    }


}
